package com.onpositive.realmview.queryeditor;

import java.util.ArrayList;

import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;

import com.onpositive.commons.platform.registry.IAdaptable2;

public final class DropMoveAdapter implements DropTargetListener {

	private ColumnViewer viewer;

	public DropMoveAdapter(ColumnViewer viewer) {
		this.viewer = viewer;
	}

	public void dragEnter(DropTargetEvent event) {

	}

	public void dragLeave(DropTargetEvent event) {

	}

	public void dragOperationChanged(DropTargetEvent event) {

	}

	public void dragOver(DropTargetEvent event) {
		checkDrop(viewer, event);
	}

	private void checkDrop(final ColumnViewer cl, DropTargetEvent event) {
		if (event.data == null)
			event.data = cl.getSelection();
		if (event.data instanceof StructuredSelection && event.item != null) {
			Object[] array = getElementsToDrop(event);
			Object dta = event.item.getData();
			if (dta instanceof IAdaptable2) {
				Object element = ((IAdaptable2) dta).getAdapter(ICanDrop.class);
				ICanDrop d = (ICanDrop) element;
				if (d != null) {
					if (d.canDrop(array)) {
						event.detail = DND.DROP_MOVE;
						return;
					}
				}
			}
		}
		event.detail = DND.DROP_NONE;
	}

	protected Object[] getElementsToDrop(DropTargetEvent event) {
		StructuredSelection sel = (StructuredSelection) event.data;
		ArrayList<Object> l = new ArrayList<Object>();
		for (Object c : sel.toArray()) {
			if (canBeDropped(c))
				l.add(c);
		}
		Object[] array = l.toArray();
		return array;
	}

	protected boolean canBeDropped(Object c) {
		// TODO Always true for now; Make actual checking
		return true;
	}

	public void drop(DropTargetEvent event) {
		if (event.data instanceof StructuredSelection) {
			Object[] array = getElementsToDrop(event);
			Object dta = event.item.getData();
			if (dta instanceof IAdaptable2) {
				Object element = ((IAdaptable2) dta).getAdapter(ICanDrop.class);
				ICanDrop d = (ICanDrop) element;
				if (d != null) {
					d.drop(array);
					event.detail = DND.DROP_MOVE;
					return;
				}
			}
		}
	}

	public void dropAccept(DropTargetEvent event) {
		checkDrop(viewer, event);
	}
}